1 00:00:01,640 --> 00:00:02,180 Hey there. 2 00:00:02,180 --> 00:00:03,050 Welcome back. 3 00:00:03,050 --> 00:00:07,820 In this lecture we're going to be scripting the last tool for our project which is our grenade. 4 00:00:07,850 --> 00:00:12,440 The purpose of this tool is to give our players the ability to do splash damage to zombies when they 5 00:00:12,440 --> 00:00:15,080 feel overwhelmed with a large crowd of zombies. 6 00:00:15,080 --> 00:00:20,090 So when we activate this tool, it's going to fire to the server the position of our mouse, and it's 7 00:00:20,090 --> 00:00:25,340 going to throw our grenade, and then it's going to blow up and deal a whole bunch of splash damage 8 00:00:25,340 --> 00:00:26,600 to the zombies. 9 00:00:26,600 --> 00:00:28,700 And of course, we can hold more than one grenade. 10 00:00:28,700 --> 00:00:33,410 Right now I'm holding nine and I can spam click all of these grenades and throw them out, and it's 11 00:00:33,410 --> 00:00:35,480 just going to blow up all of these guys. 12 00:00:36,530 --> 00:00:38,330 So let's get started. 13 00:00:39,230 --> 00:00:43,880 Inside of server storage and inside of tools, we have our grenade tool right here. 14 00:00:43,880 --> 00:00:46,100 And it's just one mesh part inside of there. 15 00:00:46,100 --> 00:00:48,470 Let me go ahead and parent it to the workspace. 16 00:00:48,470 --> 00:00:50,090 This is our grenade model. 17 00:00:50,240 --> 00:00:54,290 And the plan is we're going to have the player activate this tool. 18 00:00:54,290 --> 00:00:57,920 And when they activate it we're going to fire to the server the position of our mouse. 19 00:00:57,920 --> 00:01:00,830 That way the server can calculate the direction to throw the grenade. 20 00:01:00,830 --> 00:01:05,570 We're going to throw it and then it's going to blow up and deal any splash damage to any zombies that 21 00:01:05,570 --> 00:01:06,170 are nearby. 22 00:01:06,170 --> 00:01:07,160 The explosion. 23 00:01:08,190 --> 00:01:12,210 So what we can go ahead and do is create a new module script inside of here to store all of the different 24 00:01:12,210 --> 00:01:14,370 properties for the grenade. 25 00:01:14,670 --> 00:01:19,140 I'll just call it self and we'll go ahead and return it at the end of our module. 26 00:01:19,140 --> 00:01:23,730 And inside of here we want to define some things such as the base damage for the grenade, which I'll 27 00:01:23,730 --> 00:01:26,400 set to a value of 250 health points. 28 00:01:26,400 --> 00:01:30,450 We can also set a value of how long we want to wait before the grenade explodes. 29 00:01:30,450 --> 00:01:32,190 So this can be like the fuse time. 30 00:01:32,190 --> 00:01:34,710 We'll call it time until explosion. 31 00:01:34,710 --> 00:01:39,180 So when the player throws the grenade, how long do we want to wait until it blows up. 32 00:01:39,180 --> 00:01:41,190 And we could do a value of like three seconds. 33 00:01:41,580 --> 00:01:46,980 And then another property we want to go ahead and define is how long we should wait before we delete 34 00:01:46,980 --> 00:01:49,200 the grenade off of the map and clean it up. 35 00:01:49,200 --> 00:01:52,230 So we could call this lifetime after explosion. 36 00:01:52,230 --> 00:01:54,420 And I'll just set it to something like five seconds. 37 00:01:54,930 --> 00:02:01,740 And now I want to go ahead and define a table of the different damage ranges based on how close the 38 00:02:01,740 --> 00:02:03,690 zombie is to the explosion. 39 00:02:03,690 --> 00:02:08,820 So for example, if the zombie is within three studs of the epicenter of the explosion, that I want 40 00:02:08,820 --> 00:02:12,750 to apply a multiplier to the base damage to boost that base damage up. 41 00:02:12,750 --> 00:02:17,910 However, if the zombie is farther away from the grenade, let's say the zombies 20 studs away, then 42 00:02:17,910 --> 00:02:20,880 I want to apply a lower multiplier for the damage. 43 00:02:20,880 --> 00:02:24,630 So let's go ahead and define a table called Damage Ranges. 44 00:02:25,200 --> 00:02:30,630 And inside of here, we'll just have a whole bunch of different tables for the different damage ranges. 45 00:02:30,630 --> 00:02:35,550 We'll have a minimum and a maximum value for the range. 46 00:02:35,550 --> 00:02:38,310 So the minimum value for this first one will be zero. 47 00:02:38,310 --> 00:02:42,210 So between zero and then the max we'll do something like three studs. 48 00:02:42,870 --> 00:02:45,510 And I want this value to be inclusive. 49 00:02:45,510 --> 00:02:47,850 And I want this value to be exclusive. 50 00:02:47,850 --> 00:02:48,840 What do I mean by that. 51 00:02:48,840 --> 00:02:55,650 Well I want this to include any zombies who are within 0 to 3 studs in the explosion range. 52 00:02:55,650 --> 00:02:57,450 But I don't want to include the value of three. 53 00:02:57,450 --> 00:03:04,020 I want the distance to be any value below three, and then we could state what the multiplier is going 54 00:03:04,020 --> 00:03:04,290 to be. 55 00:03:04,290 --> 00:03:08,730 For example, if they're within three studs, we'll set the multiplier to something like three. 56 00:03:09,210 --> 00:03:11,580 And then what we can go ahead and do is copy this. 57 00:03:11,580 --> 00:03:13,980 And now the minimum for this one is going to be three. 58 00:03:13,980 --> 00:03:15,930 So anywhere between three. 59 00:03:15,930 --> 00:03:17,790 And we could do something like five studs. 60 00:03:17,790 --> 00:03:21,270 So if they're between 3 and 5 studs three is inclusive. 61 00:03:21,270 --> 00:03:24,870 And we're excluding five because five is going to be the next damage range. 62 00:03:24,870 --> 00:03:27,780 And we could do a multiplier of like two again. 63 00:03:27,780 --> 00:03:29,040 We'll copy this. 64 00:03:29,770 --> 00:03:35,830 And here we could do a range of, let's say between 5 and 7 studs. 65 00:03:35,830 --> 00:03:38,860 And here we'll do a multiplier of 1.5. 66 00:03:39,250 --> 00:03:40,180 We'll copy this. 67 00:03:40,180 --> 00:03:41,170 We'll do another range. 68 00:03:41,170 --> 00:03:44,680 This one's going to be from seven to let's say nine studs. 69 00:03:44,680 --> 00:03:46,870 We'll do a damage multiplier of one. 70 00:03:47,780 --> 00:03:49,070 We'll copy this. 71 00:03:49,070 --> 00:03:57,440 And then between, let's say, nine studs all the way up to 13 studs will have a multiplier of 0.9. 72 00:03:59,160 --> 00:04:06,720 If we're between 13 studs and let's say 17, then we'll have a multiplier of 0.7. 73 00:04:07,260 --> 00:04:13,050 And then if we have a range between let's say 17 up to 25. 74 00:04:13,050 --> 00:04:16,620 So I want the range for my explosion to be up to 25 studs away. 75 00:04:16,620 --> 00:04:18,660 Then we'll have the multiplier be 0.5. 76 00:04:19,110 --> 00:04:26,520 The next thing I want to go ahead and define is all of the properties for the explosion for our grenade. 77 00:04:26,520 --> 00:04:33,030 So we're going to be using an explosion instance to detect what parts we hit or if we hit any zombies 78 00:04:33,030 --> 00:04:33,630 in the map. 79 00:04:33,630 --> 00:04:37,590 And that means we want to go ahead and modify some of these properties in the explosion, such as the 80 00:04:37,590 --> 00:04:43,650 explosion or blast pressure, the radius of the explosion, the different types of the explosion and 81 00:04:43,650 --> 00:04:44,610 stuff like that. 82 00:04:45,000 --> 00:04:48,600 So let's go ahead and define some explosion properties. 83 00:04:48,600 --> 00:04:53,730 For example, we'll set the blast pressure to something like 30,000. 84 00:04:53,760 --> 00:04:59,040 I don't want it to be the default of 500,000, because that means when it explodes, it's going to shoot 85 00:04:59,040 --> 00:05:02,250 the limbs of the zombies super far away, which I don't want. 86 00:05:02,640 --> 00:05:07,050 The next property is the blast radius, and I want it to be up to 25 studs away. 87 00:05:07,860 --> 00:05:11,670 There's a property called destroy joint radius percent. 88 00:05:11,670 --> 00:05:12,810 And that means. 89 00:05:13,490 --> 00:05:16,010 The percentage or the distance inside of here. 90 00:05:16,010 --> 00:05:22,340 Do we want to destroy joints of characters that hit this explosion or the explosion? 91 00:05:22,340 --> 00:05:23,450 Hit that character. 92 00:05:23,450 --> 00:05:27,620 I don't want to destroy the joints of any zombies that get hit by this explosion, so I'm just going 93 00:05:27,620 --> 00:05:29,240 to set the value equal to zero. 94 00:05:29,840 --> 00:05:36,590 We're going to set the explosion type equal to the enemy explosion type of no craters. 95 00:05:36,590 --> 00:05:39,620 So this is specifically if you have terrain in your game. 96 00:05:39,620 --> 00:05:41,780 If the explosion type was set to craters. 97 00:05:41,780 --> 00:05:44,000 And that means it would create divots in the terrain. 98 00:05:44,000 --> 00:05:45,920 But I'm going to set it to no craters. 99 00:05:46,250 --> 00:05:48,830 And then there's a property called visible. 100 00:05:48,830 --> 00:05:53,330 And I want to set that equal to false, because we're going to be using our own custom particles. 101 00:05:53,330 --> 00:05:58,730 Setting visible to false means it disables the default particles for the explosion. 102 00:05:58,730 --> 00:06:01,760 And that way we can replace it with our own custom particles. 103 00:06:02,940 --> 00:06:08,640 And that's because inside of the grenade, inside of the handle, we have the sound of the explosion, 104 00:06:08,640 --> 00:06:09,720 which I'll play here. 105 00:06:10,380 --> 00:06:15,300 And then we have two particle emitters, one for the explosion and one for the smoke. 106 00:06:15,300 --> 00:06:17,460 So I'm going to go ahead and select both of those. 107 00:06:17,460 --> 00:06:23,520 And I have a plugin which allows me to emit, let's say 100 particles out of the particle emitters. 108 00:06:23,520 --> 00:06:26,880 If you would like to use this plugin I'll have it attached to the lecture. 109 00:06:26,880 --> 00:06:28,590 But if I go ahead and hit emit. 110 00:06:29,180 --> 00:06:32,480 That's going to be the explosion we're using for our grenade. 111 00:06:32,480 --> 00:06:37,400 So we can go ahead and define how many particles we would like to spit out of those particle emitters. 112 00:06:37,400 --> 00:06:41,630 So for the explosion particle amount we could do 100. 113 00:06:41,630 --> 00:06:47,090 And then for the smoke particle amount we'll also do a value of 100. 114 00:06:47,850 --> 00:06:52,830 Okay, now that we have that done, what we can go ahead and do is create a new local script inside 115 00:06:52,830 --> 00:06:53,730 of our grenade. 116 00:06:54,520 --> 00:07:00,400 We'll be using that same template as before, and I'm only going to need a section to listen to some 117 00:07:00,400 --> 00:07:01,180 event handlers. 118 00:07:01,180 --> 00:07:06,610 I'm not going to need any functions, and what I'm going to do is I'm going to grab the player service 119 00:07:06,610 --> 00:07:07,960 to get the local player. 120 00:07:09,540 --> 00:07:13,440 So we'll do player is equal to players dot local player. 121 00:07:13,440 --> 00:07:16,170 And that's because I want to get the mouse object of my player. 122 00:07:16,170 --> 00:07:19,230 So mouse is equal to player get mouse. 123 00:07:21,160 --> 00:07:24,610 And then we can go ahead and make a reference to our tool, which is script dot parent. 124 00:07:24,610 --> 00:07:31,510 And then we also want to create a remote event inside of our tool to communicate between the local script 125 00:07:31,510 --> 00:07:33,550 and the server script we're going to have in this grenade. 126 00:07:33,550 --> 00:07:35,890 So let's go ahead and create a new remote event in here. 127 00:07:35,890 --> 00:07:38,980 And I'm going to call this my grenade event. 128 00:07:39,070 --> 00:07:42,280 And then we can go ahead and refer to this grenade event. 129 00:07:42,280 --> 00:07:44,800 So that's going to be tool dot grenade event. 130 00:07:45,520 --> 00:07:48,490 And I want to listen for when my tool is activated. 131 00:07:48,490 --> 00:07:53,020 And when it is we're going to use this grenade event and fire to the server. 132 00:07:53,020 --> 00:07:56,770 And I want to give the server the position of my mouse in the workspace. 133 00:07:56,770 --> 00:08:00,550 So we're going to pass mouse dot hit dot position. 134 00:08:00,550 --> 00:08:06,100 And that way the server can use this position to calculate what direction the grenade should be thrown 135 00:08:06,100 --> 00:08:08,560 based on the position of my character model. 136 00:08:09,910 --> 00:08:13,810 So now we can go ahead and create a server script inside of our grenade. 137 00:08:14,960 --> 00:08:16,550 We use the same common template. 138 00:08:16,550 --> 00:08:19,160 I'll delete this section, get rid of that section. 139 00:08:19,160 --> 00:08:22,970 And then we want to go ahead and get the player service. 140 00:08:24,770 --> 00:08:28,070 And I'm also going to be using the debris service once again. 141 00:08:30,350 --> 00:08:33,560 And then we can go ahead and make a reference to our tool script dot parent. 142 00:08:33,590 --> 00:08:36,050 We'll go ahead and get the properties for the tool. 143 00:08:36,050 --> 00:08:38,870 So we'll require tool dot properties. 144 00:08:38,870 --> 00:08:41,750 And then I also want to get the grenade event as well. 145 00:08:42,410 --> 00:08:45,320 That's equal to tool dot grenade event. 146 00:08:46,750 --> 00:08:51,850 Now, since I want to give my player the ability to hold more than one grenade inside of this tool. 147 00:08:52,240 --> 00:08:57,370 We have a couple attributes on this grenade called grenades left and Max grenades, which tells us up 148 00:08:57,370 --> 00:09:02,950 to how many grenades can we store in this tool and how many grenades do we currently have left? 149 00:09:02,950 --> 00:09:07,660 That way, when the player goes to our shop and wants to purchase a grenade, if they don't have this 150 00:09:07,660 --> 00:09:12,070 grenade tool in their inventory, then we're just going to give them this new grenade tool. 151 00:09:12,070 --> 00:09:16,630 And if they do have this grenade tool in their inventory, then we'll just increment this grenades left 152 00:09:16,630 --> 00:09:18,850 attribute on the grenade tool. 153 00:09:18,850 --> 00:09:20,590 And we'll be doing that in a little bit. 154 00:09:21,300 --> 00:09:24,960 But for right now, what we want to go ahead and do is we want to listen to that grenade event when 155 00:09:24,960 --> 00:09:25,560 it's fired. 156 00:09:25,560 --> 00:09:30,630 So on server event we're going to connect a function, get the player, and then we'll get the mouse 157 00:09:30,630 --> 00:09:32,700 position the player provides to us. 158 00:09:32,730 --> 00:09:38,460 Now of course we want to make sure that the player that fired this event is actually the player that 159 00:09:38,460 --> 00:09:42,000 has this tool equipped, which is why we're using the player service. 160 00:09:42,000 --> 00:09:45,540 So we're going to check if this player, if it's not equal to. 161 00:09:45,540 --> 00:09:51,600 And we're going to use the get player from character function and pass the parent of this tool, which 162 00:09:51,600 --> 00:09:53,100 should be the player's character. 163 00:09:53,280 --> 00:09:57,690 If these are two different players, then we're going to return because that means an exploiter tried 164 00:09:57,690 --> 00:09:59,730 to fire this event for another player. 165 00:10:00,570 --> 00:10:05,790 Another thing we want to make sure of is that the attribute of grenades left is greater than one. 166 00:10:05,790 --> 00:10:12,810 So if our tool get attribute grenades left, if that is equal to zero, then we're going to return. 167 00:10:14,110 --> 00:10:16,990 Otherwise we can go ahead and throw the grenade. 168 00:10:16,990 --> 00:10:20,320 And that first means we want to decrease how many grenades are left in the tool. 169 00:10:20,320 --> 00:10:28,510 So we'll do tool set attribute grenades left equal to tool get attribute grenades left subtracted by 170 00:10:28,510 --> 00:10:29,140 one. 171 00:10:29,710 --> 00:10:34,090 And then we'll go ahead and get the character which is tool dot parent. 172 00:10:35,080 --> 00:10:38,200 We'll go ahead and get the player which is equal to players. 173 00:10:38,200 --> 00:10:42,310 Get player from character and we'll pass the character. 174 00:10:44,010 --> 00:10:50,160 And now what I want to do is I want to create a clone of the handle of my grenade, and then I'm going 175 00:10:50,160 --> 00:10:57,660 to basically position the clone of this handle at my player's character and then throw it in a particular 176 00:10:57,660 --> 00:10:58,170 direction. 177 00:10:58,170 --> 00:11:00,330 So let's go ahead and make a clone of that. 178 00:11:00,330 --> 00:11:03,360 So we'll call it actually grenade clone. 179 00:11:03,360 --> 00:11:06,180 And that's going to be equal to my tool dot handle clone. 180 00:11:07,760 --> 00:11:12,950 And we're going to make sure that the grenade clone is opaque. 181 00:11:12,950 --> 00:11:14,810 So we're going to set transparency equal to zero. 182 00:11:14,810 --> 00:11:21,560 And that's because the plan is that once the player runs out of grenades, let's say their grenade attribute 183 00:11:21,560 --> 00:11:22,730 gets set to zero. 184 00:11:22,730 --> 00:11:25,220 Then we want to make the handle invisible. 185 00:11:25,220 --> 00:11:29,990 But we're going to make sure that when we're actually throwing a grenade that it isn't invisible. 186 00:11:30,770 --> 00:11:36,170 And they're also going to set can collide on the handle equal to true because it's not enabled by default. 187 00:11:36,290 --> 00:11:40,790 And then we're going to set the parent of this grenade clone equal to the workspace. 188 00:11:40,790 --> 00:11:43,310 We're going to position this grenade clone. 189 00:11:43,790 --> 00:11:47,690 It's going to be equal to our character's humanoid root part. 190 00:11:48,460 --> 00:11:49,480 Position. 191 00:11:51,330 --> 00:11:57,540 And then I want to position it a little bit in front of our players character, so we can add an additional 192 00:11:57,540 --> 00:11:58,230 vector to this. 193 00:11:58,260 --> 00:12:04,050 We're going to get our character's humanoid root part, dot keyframe, dot look vector and multiply 194 00:12:04,050 --> 00:12:05,160 that by two. 195 00:12:05,190 --> 00:12:10,050 So the position we're setting the grenade to is going to be two studs in front of our humanoid root 196 00:12:10,050 --> 00:12:10,680 part. 197 00:12:10,680 --> 00:12:14,520 And then we want to go ahead and calculate the direction we need to throw this grenade. 198 00:12:14,520 --> 00:12:19,050 And that's going to be equal to the mouse position passed to us from the client. 199 00:12:19,260 --> 00:12:23,790 And we're going to subtract that by the position of our humanoid root part. 200 00:12:27,330 --> 00:12:31,830 And then we're going to get a unit normalized copy of that vector. 201 00:12:31,830 --> 00:12:38,400 And then to be able to throw this grenade clone, we can go ahead and set the assembly linear velocity 202 00:12:38,400 --> 00:12:40,170 to be equal to this direction. 203 00:12:40,170 --> 00:12:41,640 We want to throw the grenade. 204 00:12:41,790 --> 00:12:46,410 Of course, since the length of this direction is only one stud, that means this force is going to 205 00:12:46,410 --> 00:12:47,280 be incredibly weak. 206 00:12:47,280 --> 00:12:51,360 So we're going to bump up the force of this by multiplying the direction by 30. 207 00:12:51,690 --> 00:12:54,120 So that way we actually have a little bit of force in our throw. 208 00:12:54,120 --> 00:13:01,230 And then we also want to multiply or add a new vector three to this to have a curve to our throw. 209 00:13:01,230 --> 00:13:04,020 So we can kind of throw it up and then it goes down. 210 00:13:04,020 --> 00:13:07,560 So let's go ahead and apply a force in the y direction as well. 211 00:13:07,560 --> 00:13:10,440 We could do a value of like 55 in the y direction. 212 00:13:10,440 --> 00:13:15,990 And now we're going to be applying a force in the direction the player wants to throw it towards that 213 00:13:15,990 --> 00:13:18,570 direction with a bit of a force upwards. 214 00:13:18,570 --> 00:13:20,520 So it's like you know, we're actually throwing it. 215 00:13:21,160 --> 00:13:25,150 And then once we do that, we want to go ahead and yield for our properties. 216 00:13:25,150 --> 00:13:27,310 Dot time until explosion. 217 00:13:27,700 --> 00:13:31,150 And then here is where we should create a new explosion instance. 218 00:13:31,150 --> 00:13:34,300 Blow up the grenade and detect if we hit anything. 219 00:13:35,320 --> 00:13:40,630 So we want to create a new explosion, but we also want to apply all of the properties for that explosion 220 00:13:40,630 --> 00:13:42,340 from our module script. 221 00:13:42,580 --> 00:13:44,500 So let's go ahead and create a new function. 222 00:13:44,500 --> 00:13:47,290 I'm going to call this function Create Explosion. 223 00:13:47,290 --> 00:13:51,520 And we'll pass all of the explosion properties to this function. 224 00:13:51,910 --> 00:13:56,140 And we'll go ahead and get a new explosion equal to instance dot new explosion. 225 00:13:56,140 --> 00:14:02,650 And for every property and value in explosion properties we'll apply that to our explosion. 226 00:14:05,080 --> 00:14:07,810 And then we can go ahead and return the explosion back. 227 00:14:07,810 --> 00:14:13,870 And we don't want to parent the explosion to the workspace yet, because once we parent the explosion 228 00:14:13,870 --> 00:14:16,780 to the workspace, that's when it's going to blow up. 229 00:14:17,290 --> 00:14:25,120 So we'll get that explosion from our create explosion function and pass properties, not explosion properties. 230 00:14:26,510 --> 00:14:31,640 And before we parent the explosion to the workspace, we want to go ahead and listen to the hit event. 231 00:14:31,640 --> 00:14:32,630 And it says fires. 232 00:14:32,630 --> 00:14:36,860 When the explosion hits a bass part within its explosion blast radius. 233 00:14:36,860 --> 00:14:41,810 So we'll connect a function to this, and we're going to get past the part that we hit and then the 234 00:14:41,810 --> 00:14:44,540 distance from the epicenter of the explosion. 235 00:14:44,780 --> 00:14:46,850 So we'll call this our hit part. 236 00:14:46,850 --> 00:14:48,590 And then we'll get the distance. 237 00:14:49,500 --> 00:14:57,210 And the issue here now is that since there are so many different limbs inside of a zombie, we only 238 00:14:57,210 --> 00:15:00,540 want to make sure that we hurt a zombie once. 239 00:15:00,540 --> 00:15:06,960 Because if we listen and hit or apply damage for every single limb that's in the zombie, then this 240 00:15:06,960 --> 00:15:09,060 grenade is going to be way too overpowered. 241 00:15:09,060 --> 00:15:15,240 So what we can go ahead and do is verify that this hit part is actually a humanoid root part. 242 00:15:15,330 --> 00:15:21,600 And since there's only one humanoid root part per zombie, then we're guaranteed to only hurt them once. 243 00:15:21,600 --> 00:15:29,220 So if this hip part's name is not equal to humanoid root part, then we're just going to return. 244 00:15:30,390 --> 00:15:33,420 Otherwise, what we can go ahead and do is get the humanoid. 245 00:15:33,420 --> 00:15:37,740 So that's going to be equal to hip part dot parent find first child which is a humanoid. 246 00:15:38,280 --> 00:15:42,900 If for some reason there is no humanoid, then we're just going to return. 247 00:15:43,690 --> 00:15:46,780 Otherwise, we need to check if this humanoid belongs to a player. 248 00:15:46,780 --> 00:15:49,330 Because if it belongs to a player, we don't want to hurt them. 249 00:15:49,330 --> 00:15:57,220 So if players get player from character, we pass hit part dot parent and we get a player from that, 250 00:15:57,220 --> 00:15:58,870 then we're going to return as well. 251 00:16:00,600 --> 00:16:06,600 Otherwise, what we can go ahead and do is we want to create a function for getting the damage we should 252 00:16:06,600 --> 00:16:11,550 apply based on the distance away from the epicenter of the explosion. 253 00:16:12,590 --> 00:16:18,080 So what we can go ahead and do is create a function and we'll call it get damage, and we'll get past 254 00:16:18,080 --> 00:16:21,140 the distance away from the epicenter of the explosion. 255 00:16:21,140 --> 00:16:25,400 And then we can go ahead and loop through every single range that is inside of our properties, dot 256 00:16:25,400 --> 00:16:27,050 damage ranges. 257 00:16:27,260 --> 00:16:34,190 And what we want to do is we want to check if this number or this distance is in between those two ranges, 258 00:16:34,190 --> 00:16:35,630 the minimum and the maximum. 259 00:16:35,750 --> 00:16:41,300 However, because I want the minimum value to be inclusive, but I don't want to include the max value 260 00:16:41,300 --> 00:16:46,430 because the max value should be for the next range, then what I'm going to do is I'm going to create 261 00:16:46,430 --> 00:16:49,610 a function called number in range. 262 00:16:49,610 --> 00:16:53,750 We'll get past a number and then a minimum and a maximum value. 263 00:16:53,750 --> 00:16:59,810 And since I want the maximum value to be not included in this calculation, what we can go ahead and 264 00:16:59,810 --> 00:17:01,250 do is we can return. 265 00:17:02,250 --> 00:17:12,630 If our number is greater than or equal to the minimum number, and our number is less than the max number, 266 00:17:12,630 --> 00:17:18,390 not less than or equal to, but less than the max number, then we're going to return true. 267 00:17:18,390 --> 00:17:20,550 Otherwise we'll return false. 268 00:17:20,880 --> 00:17:22,860 So we're inclusive with the minimum number. 269 00:17:22,860 --> 00:17:25,350 But we're not inclusive with the maximum number. 270 00:17:26,010 --> 00:17:32,610 Then we can go ahead and check to see if this distance is within this particular range. 271 00:17:32,610 --> 00:17:36,720 So if number in range will pass our distance here. 272 00:17:36,720 --> 00:17:39,540 And the minimum value is going to be our range dot min. 273 00:17:39,540 --> 00:17:42,120 And the max is going to be range dot max. 274 00:17:42,540 --> 00:17:48,090 If it's within that range then we can go ahead and return the damage we should apply, which is going 275 00:17:48,090 --> 00:17:50,400 to be our properties dot base damage. 276 00:17:50,400 --> 00:17:53,970 And we want to multiply this by the multiplier inside of this range. 277 00:17:53,970 --> 00:17:55,830 So range dot multiplier. 278 00:17:57,080 --> 00:17:57,770 Otherwise. 279 00:17:57,770 --> 00:18:01,910 Let's just say for some reason, somehow we didn't find a range in here. 280 00:18:01,910 --> 00:18:05,600 Then I'm just going to return the properties of base damage. 281 00:18:05,600 --> 00:18:13,040 But this hit event shouldn't fire or detect any parts that are outside of the blast radius for our explosion, 282 00:18:13,040 --> 00:18:16,910 so we shouldn't have to worry about damaging any zombies that are too far away. 283 00:18:17,300 --> 00:18:21,920 But now that we have our get damage function, we can go ahead and get the damage. 284 00:18:21,920 --> 00:18:24,950 So get damage and we'll pass the distance. 285 00:18:25,670 --> 00:18:31,400 And then we can refer to that humanoid and use the take damage function and apply that damage on that 286 00:18:31,400 --> 00:18:32,210 zombie. 287 00:18:33,290 --> 00:18:41,030 And another thing we should account for is if there is a who last damaged value in there. 288 00:18:41,030 --> 00:18:46,130 So that way we can credit that kill or death of the zombie to this player. 289 00:18:46,130 --> 00:18:54,410 So if the hip part dot parent find first child who last damaged, then we can go ahead and set hip part 290 00:18:54,440 --> 00:18:59,660 dot parent dot who last damaged dot value equal to this player. 291 00:19:01,390 --> 00:19:07,510 Now that we are successfully listening to this hit event, we can go ahead and set the position of our 292 00:19:07,510 --> 00:19:11,230 explosion to be equal to the grenade clone dot position. 293 00:19:11,230 --> 00:19:15,640 So wherever our grenade clone is at, we're going to set the explosion to that position, and then we 294 00:19:15,640 --> 00:19:21,070 can go ahead and set the parent of this explosion equal to the workspace. 295 00:19:21,070 --> 00:19:25,060 Or actually we'll make it a child of our grenade clone. 296 00:19:25,510 --> 00:19:30,940 And before we actually want to blow it up, we're also going to anchor our grenade clone. 297 00:19:30,940 --> 00:19:32,860 So that way it doesn't go flying away. 298 00:19:32,860 --> 00:19:34,570 So we're going to anchor it in place. 299 00:19:34,570 --> 00:19:37,000 And then the explosion is going to happen. 300 00:19:37,000 --> 00:19:43,210 And once the explosion happens we're going to set the grenade clones transparency equal to one. 301 00:19:43,210 --> 00:19:47,320 And then we want to go ahead and emit particles out of our grenade clone. 302 00:19:47,320 --> 00:19:55,300 So grenade clone dot explosion emitter we're going to emit from the properties dot explosion particle 303 00:19:55,300 --> 00:19:55,840 amount. 304 00:19:55,840 --> 00:19:59,530 And then inside of the grenade clone we're going to get the smoke emitter. 305 00:19:59,530 --> 00:20:03,130 And we're going to emit the properties dot smoke particle amount. 306 00:20:03,130 --> 00:20:06,160 And then we also want to go ahead and play the explosion sound. 307 00:20:06,160 --> 00:20:09,070 So grenade clone dot explosion sound. 308 00:20:10,300 --> 00:20:11,590 We're going to play that. 309 00:20:11,590 --> 00:20:18,100 And finally we can go ahead and use the debris service and add an item which is going to be our grenade 310 00:20:18,100 --> 00:20:18,550 clone. 311 00:20:18,550 --> 00:20:23,530 And we're going to destroy after the lifetime after explosion. 312 00:20:23,950 --> 00:20:24,760 Cool. 313 00:20:25,120 --> 00:20:30,760 The next thing we want to go ahead and do is we want to be able to notify or tell the player how many 314 00:20:30,760 --> 00:20:36,070 grenades they have left inside of the grenade, because they're not going to be able to see these attributes. 315 00:20:36,070 --> 00:20:41,230 So what we should do is we should update the name of the tool, and it should tell them how many grenades 316 00:20:41,230 --> 00:20:42,400 they have left. 317 00:20:42,880 --> 00:20:50,050 So because we are manipulating the attributes of our tool here, we should listen for when those attributes 318 00:20:50,050 --> 00:20:50,590 change. 319 00:20:50,590 --> 00:20:55,270 So we're going to listen to the attribute change event, connect a function and get the name of the 320 00:20:55,270 --> 00:20:56,620 attribute that changed. 321 00:20:57,680 --> 00:21:03,530 And if the name of that attribute is equal to the grenades left attribute, then we can go ahead and 322 00:21:03,530 --> 00:21:10,610 set the name of the tool equal to grenade, and then we can put inside of parentheses how many grenades 323 00:21:10,610 --> 00:21:11,480 are left. 324 00:21:11,480 --> 00:21:16,730 So we will make sure to concatenate this with the tool get attribute. 325 00:21:17,060 --> 00:21:20,090 And that's going to be grenades left. 326 00:21:21,050 --> 00:21:22,520 And concatenate that. 327 00:21:23,300 --> 00:21:23,780 Otherwise. 328 00:21:23,780 --> 00:21:31,130 What we can do is we can check if the tool get attribute grenades left is equal to zero, and if it 329 00:21:31,130 --> 00:21:35,990 is, then that means we should make the handle of the grenade or this model. 330 00:21:35,990 --> 00:21:37,010 We should make it invisible. 331 00:21:37,010 --> 00:21:39,260 So that way it looks like we don't have any grenades left. 332 00:21:39,260 --> 00:21:44,540 So tool dot handle dot transparency set it equal to one. 333 00:21:44,540 --> 00:21:50,210 Otherwise we can go ahead and set tool dot handle dot transparency back to be opaque. 334 00:21:51,800 --> 00:21:56,270 And then the last thing we can do is just copy this code right here and paste it inside of the main 335 00:21:56,270 --> 00:21:56,840 section. 336 00:21:56,840 --> 00:22:01,820 So that way when we're initializing this tool, it's going to update the name of the grenade to reflect 337 00:22:01,820 --> 00:22:03,560 how many grenades are left. 338 00:22:04,460 --> 00:22:04,970 Okay. 339 00:22:04,970 --> 00:22:08,300 So let's go ahead and test what we've gotten written down so far. 340 00:22:08,330 --> 00:22:12,620 I'm going to move this grenade into my starter pack. 341 00:22:13,140 --> 00:22:15,540 And then we'll go and play test. 342 00:22:17,620 --> 00:22:20,170 And unfortunately, we we got an error. 343 00:22:20,200 --> 00:22:22,540 Oh, that's because it's from our shop handler. 344 00:22:22,540 --> 00:22:26,560 Because it's trying to find the grenade in server storage, but it's not inside of there. 345 00:22:26,560 --> 00:22:28,810 So I'm just going to ignore that error for now. 346 00:22:28,810 --> 00:22:30,610 But we can go ahead and play our game. 347 00:22:31,900 --> 00:22:34,660 And let me see if I can go ahead and throw it. 348 00:22:34,660 --> 00:22:36,610 So I click there you go. 349 00:22:36,610 --> 00:22:38,230 There's our grenade and it should blow up. 350 00:22:38,680 --> 00:22:39,820 Boom. 351 00:22:39,940 --> 00:22:44,500 As you can see, the grenade in our hand is now invisible because we don't have any grenades left. 352 00:22:44,740 --> 00:22:49,810 So now what we should do is we should implement the ability for us to open up the shop and buy more 353 00:22:49,810 --> 00:22:54,160 grenades and add extra grenades into our grenade tool. 354 00:22:55,060 --> 00:23:02,350 So inside of the shop handler, when the player wants to purchase a tool and we clone it and give it 355 00:23:02,350 --> 00:23:07,900 to him, we specifically want to check if this tool is going to be a grenade. 356 00:23:07,900 --> 00:23:15,760 So if the name of the item the player is trying to buy is equal to grenade, then we don't want to create 357 00:23:15,760 --> 00:23:16,960 or give them a new tool. 358 00:23:16,960 --> 00:23:21,640 Instead, we want to check if the player already has a grenade tool on them, and if they do, we want 359 00:23:21,640 --> 00:23:27,370 to go ahead and change the attribute of grenades left on that tool so we can go ahead and see if we 360 00:23:27,370 --> 00:23:29,410 can find a grenade tool on them. 361 00:23:29,530 --> 00:23:34,900 We'll call this grenade tool and we'll set it equal to nil for now because we're going to. 362 00:23:35,480 --> 00:23:42,200 Check and loop through every single tool that is inside of the player's backpack. 363 00:23:42,200 --> 00:23:45,110 So in player backpack, get children. 364 00:23:45,110 --> 00:23:49,970 And that's because the name of the tool is not going to be exactly grenade. 365 00:23:49,970 --> 00:23:55,340 Because if you remember inside of our server script, we're updating the name of the tool to reflect 366 00:23:55,340 --> 00:23:56,540 how many grenades are left. 367 00:23:56,540 --> 00:24:01,940 So we need to loop through all the tools in the player's backpack and check to see if the name of this 368 00:24:01,940 --> 00:24:04,490 tool includes the word of grenade. 369 00:24:04,490 --> 00:24:07,340 So if string dot find. 370 00:24:08,040 --> 00:24:09,750 Inside of this tool's name. 371 00:24:09,750 --> 00:24:11,490 The word of grenade. 372 00:24:11,520 --> 00:24:16,650 Then that means they're grenade tools inside of their backpack, and we can go ahead and set the grenade 373 00:24:16,680 --> 00:24:19,050 tool variable equal to the tool we found. 374 00:24:19,050 --> 00:24:20,670 And then we'll just break out of this loop. 375 00:24:21,410 --> 00:24:22,100 Otherwise. 376 00:24:22,100 --> 00:24:25,310 Let's say we didn't find the grenade tool in their backpack. 377 00:24:25,310 --> 00:24:28,520 Well, that could mean that they are holding it instead. 378 00:24:28,520 --> 00:24:35,960 So if we did not find a grenade tool yet, then what we can go ahead and do is we'll set grenade tool 379 00:24:35,960 --> 00:24:42,920 equal to player dot character, find first child, which is a tool. 380 00:24:43,660 --> 00:24:47,230 So whatever tool the player is holding will set to grenade tool. 381 00:24:47,230 --> 00:24:51,970 Now of course the player might not have any grenade tool on them at all. 382 00:24:51,970 --> 00:24:57,130 So what we need to do instead is we need to check if we have a grenade tool. 383 00:24:57,130 --> 00:25:01,360 And this particular tool has the attribute of grenades left. 384 00:25:01,360 --> 00:25:04,450 So that way we know for sure that yep this is a grenade. 385 00:25:04,450 --> 00:25:13,390 So if there's a grenade tool and we have on this grenade tool the attribute of grenades left. 386 00:25:15,210 --> 00:25:19,260 Then we can go ahead and update the property on this grenade tool. 387 00:25:19,290 --> 00:25:27,060 However, we only want to do that if the grenades left inside of our grenade is not already equal to 388 00:25:27,060 --> 00:25:28,950 the max grenades that we can hold. 389 00:25:28,980 --> 00:25:37,560 So if grenade tool get attribute grenades left, if that's equal to the grenade tool, get attribute 390 00:25:37,560 --> 00:25:43,950 of max grenades, then we're just going to return because the player can't buy any more grenades. 391 00:25:43,950 --> 00:25:46,440 They already have the maximum amount allowed. 392 00:25:47,160 --> 00:25:56,100 Otherwise we can go ahead and set on this attribute of grenades left to be equal to grenade tool. 393 00:25:56,100 --> 00:26:00,750 Get attribute grenades left plus one. 394 00:26:00,870 --> 00:26:06,930 And then we can go ahead and make sure to deduct the amount of money from the player's leader stats. 395 00:26:06,960 --> 00:26:12,600 So player dot leader stats dot money dot value is equal to the after balance. 396 00:26:12,600 --> 00:26:17,520 And then we're just going to return because we don't want to clone a new grenade tool and give it to 397 00:26:17,520 --> 00:26:17,970 them. 398 00:26:18,090 --> 00:26:19,170 However. 399 00:26:20,130 --> 00:26:25,860 If we did not find a grenade tool in this player's inventory or on their character, then we'll go ahead 400 00:26:25,860 --> 00:26:29,220 and clone the grenade tool and place it in the player's backpack. 401 00:26:29,990 --> 00:26:35,390 So now what we can go ahead and do is I'm going to move my grenade tool back inside of server storage 402 00:26:35,390 --> 00:26:36,740 and in my tools folder. 403 00:26:37,620 --> 00:26:39,660 And we're going to go and play test the game. 404 00:26:42,970 --> 00:26:46,180 Or hop into the game, and then I want to give my players some money. 405 00:26:46,180 --> 00:26:52,150 So we'll go to the server and we'll update the money to a whole bunch of money, and then we'll go back 406 00:26:52,150 --> 00:26:52,960 to the client. 407 00:26:53,380 --> 00:26:55,420 Let's go ahead and head to the shop. 408 00:26:55,420 --> 00:26:57,880 We'll open this up and let's see if we can buy a grenade. 409 00:26:57,880 --> 00:27:00,580 So if I click this boom we got one grenade. 410 00:27:00,580 --> 00:27:04,720 If I click it again as you can see now it's updating the attribute for my grenade. 411 00:27:04,720 --> 00:27:06,100 And I can keep buying it. 412 00:27:06,100 --> 00:27:10,120 And then once I've gotten ten grenades, as you can see I can't buy any more. 413 00:27:10,210 --> 00:27:14,350 So now let's go ahead and see if our grenades can hurt some zombies. 414 00:27:15,130 --> 00:27:17,950 So we'll run over here to where the zombies spawn. 415 00:27:18,160 --> 00:27:19,450 Let's go ahead and throw it. 416 00:27:19,600 --> 00:27:20,860 We'll throw a few. 417 00:27:23,290 --> 00:27:24,640 And just like that, boom! 418 00:27:24,640 --> 00:27:26,350 It killed all of our zombies. 419 00:27:26,350 --> 00:27:27,850 Let's go ahead and run over here. 420 00:27:30,070 --> 00:27:31,720 And let's throw a grenade down. 421 00:27:33,490 --> 00:27:34,810 I might have thrown that a little bit. 422 00:27:34,810 --> 00:27:35,740 Yeah, a little bit early. 423 00:27:35,740 --> 00:27:39,880 But you can see that the range of the grenade actually works just fine. 424 00:27:39,880 --> 00:27:43,720 So instead of instantly killing that zombie, it only dealt half of its health. 425 00:27:43,720 --> 00:27:44,770 Pretty cool. 426 00:27:45,580 --> 00:27:49,000 But let me throw another grenade, get them to run over it. 427 00:27:49,360 --> 00:27:49,840 There we go. 428 00:27:49,840 --> 00:27:50,980 Now they're dead. 429 00:27:52,060 --> 00:27:53,770 And then we got one last guy coming after us. 430 00:27:53,770 --> 00:27:59,020 Actually, let me just knife him up here, and then we can go and throw another grenade. 431 00:27:59,350 --> 00:28:03,970 And if you can tell, as you can see, the server's calculating the direction where I should be throwing 432 00:28:03,970 --> 00:28:04,810 the grenade. 433 00:28:05,800 --> 00:28:08,350 And it's applying that direction to the grenade. 434 00:28:08,350 --> 00:28:09,760 So it looks like I'm throwing it. 435 00:28:10,750 --> 00:28:11,650 Very cool. 436 00:28:13,080 --> 00:28:15,930 Okay, and our game should be complete. 437 00:28:15,930 --> 00:28:17,070 Congratulations. 438 00:28:17,070 --> 00:28:21,720 The only thing left for us to do is to go and playtest our game, make sure everything is working, 439 00:28:21,720 --> 00:28:24,300 and then we can go ahead and publish the game. 440 00:28:24,300 --> 00:28:26,850 I'll see you in the next lecture.